package com.csthink.common.infrastructure.util;

import com.csthink.common.infrastructure.enums.ErrorEnum;
import com.csthink.common.infrastructure.exception.BaseException;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.function.Function;

/**
 * @author <a href="mailto:security.2009@live.cn">Mars</a>
 * @since 2023-09-11
 */
public class AssertUtil {

    // isTrue
    public static <E extends RuntimeException> void isTrue(boolean expression, E e) {
        if (!expression) {
            throw e;
        }
    }

    public static void isTrue(boolean expression, ErrorEnum errorCode) {
        if (!expression) {
            throw new BaseException(errorCode);
        }
    }

    public static void isTrue(boolean expression, ErrorEnum errorCode, Object errorMsg) {
        if (!expression) {
            throw new BaseException(errorCode, errorMsg);
        }
    }

    public static void isFalse(boolean expression, ErrorEnum errorCode, Object errorMsg) {
        if (expression) {
            throw new BaseException(errorCode, errorMsg);
        }
    }

    public static <E extends RuntimeException> void isTrue(
            boolean expression, ErrorEnum errorCode, Object errorMsg, E e) {
        if (!expression) {
            throw new BaseException(errorCode, errorMsg, e);
        }
    }

    public static void isFalse(boolean expression, ErrorEnum errorCode) {
        if (expression) {
            throw new BaseException(errorCode);
        }
    }

    // isNull
    public static <E extends RuntimeException> void isNull(@Nullable Object object, E e) {
        if (object != null) {
            throw e;
        }
    }

    public static void isNull(@Nullable Object object, ErrorEnum errorCode) {
        if (object != null) {
            throw new BaseException(errorCode);
        }
    }

    public static <T> void isNull(
            @Nullable T t, ErrorEnum errorCode, Function<T, String> errorMsgFunc) {
        if (t != null) {
            throw new BaseException(errorCode, errorMsgFunc == null ? "" : errorMsgFunc.apply(t));
        }
    }

    public static void isNull(@Nullable Object object, ErrorEnum errorCode, Object errorMsg) {
        if (object != null) {
            throw new BaseException(errorCode, errorMsg);
        }
    }

    public static <T, E extends RuntimeException> void isNull(
            @Nullable T t, ErrorEnum errorCode, Function<T, String> errorMsgFunc, E e) {
        if (t != null) {
            throw new BaseException(
                    errorCode, errorMsgFunc == null ? "" : errorMsgFunc.apply(t), e);
        }
    }

    public static <E extends RuntimeException> void isNull(
            @Nullable Object object, ErrorEnum errorCode, Object errorMsg, E e) {
        if (object != null) {
            throw new BaseException(errorCode, errorMsg, e);
        }
    }

    // notNull
    public static <E extends RuntimeException> void notNull(@Nullable Object object, E e) {
        if (object == null) {
            throw e;
        }
    }

    public static void notNull(@Nullable Object object, ErrorEnum errorCode) {
        if (object == null) {
            throw new BaseException(errorCode);
        }
    }

    public static <T> void notNull(
            @Nullable T t, ErrorEnum errorCode, Function<T, String> errorMsgFunc) {
        if (t == null) {
            throw new BaseException(errorCode, errorMsgFunc == null ? "" : errorMsgFunc.apply(t));
        }
    }

    public static void notNull(@Nullable Object object, ErrorEnum errorCode, Object errorMsg) {
        if (object == null) {
            throw new BaseException(errorCode, errorMsg);
        }
    }

    public static <T, E extends RuntimeException> void notNull(
            @Nullable T t, ErrorEnum errorCode, Function<T, String> errorMsgFunc, E e) {
        if (t == null) {
            throw new BaseException(
                    errorCode, errorMsgFunc == null ? "" : errorMsgFunc.apply(t), e);
        }
    }

    public static <E extends RuntimeException> void notNull(
            @Nullable Object object, ErrorEnum errorCode, Object errorMsg, E e) {
        if (object == null) {
            throw new BaseException(errorCode, errorMsg, e);
        }
    }

    // isEmpty
    public static <E extends RuntimeException> void isEmpty(@Nullable Object object, E e) {
        if (!ObjectUtils.isEmpty(object)) {
            throw e;
        }
    }

    public static void isEmpty(@Nullable Object object, ErrorEnum errorCode) {
        if (!ObjectUtils.isEmpty(object)) {
            throw new BaseException(errorCode);
        }
    }

    public static void isEmpty(@Nullable Object object, ErrorEnum errorCode, Object errorMsg) {
        if (!ObjectUtils.isEmpty(object)) {
            throw new BaseException(errorCode, errorMsg);
        }
    }

    public static <E extends RuntimeException> void isEmpty(
            @Nullable Object object, ErrorEnum errorCode, Object errorMsg, E e) {
        if (!ObjectUtils.isEmpty(object)) {
            throw new BaseException(errorCode, errorMsg, e);
        }
    }

    // notEmpty
    public static <E extends RuntimeException> void notEmpty(@Nullable Object object, E e) {
        if (ObjectUtils.isEmpty(object)) {
            throw e;
        }
    }

    public static void notEmpty(@Nullable Object object, ErrorEnum errorCode) {
        if (ObjectUtils.isEmpty(object)) {
            throw new BaseException(errorCode);
        }
    }

    public static void notEmpty(@Nullable Object object, ErrorEnum errorCode, Object errorMsg) {
        if (ObjectUtils.isEmpty(object)) {
            throw new BaseException(errorCode, errorMsg);
        }
    }

    public static <E extends RuntimeException> void notEmpty(
            @Nullable Object object, ErrorEnum errorCode, Object errorMsg, E e) {
        if (ObjectUtils.isEmpty(object)) {
            throw new BaseException(errorCode, errorMsg, e);
        }
    }

    // hasText
    public static <E extends RuntimeException> void hasText(@Nullable String text, E e) {
        if (!StringUtils.hasText(text)) {
            throw e;
        }
    }

    public static void hasText(@Nullable String text, ErrorEnum errorCode) {
        if (!StringUtils.hasText(text)) {
            throw new BaseException(errorCode);
        }
    }

    public static void hasText(@Nullable String text, ErrorEnum errorCode, Object errorMsg) {
        if (!StringUtils.hasText(text)) {
            throw new BaseException(errorCode, errorMsg);
        }
    }

    public static <E extends RuntimeException> void hasText(
            @Nullable String text, ErrorEnum errorCode, Object errorMsg, E e) {
        if (!StringUtils.hasText(text)) {
            throw new BaseException(errorCode, errorMsg, e);
        }
    }
}
